/**
 * Created by IntelliJ IDEA.
 * User: Bezdelnick
 * Date: 9/26/12
 * Time: 9:43 AM
 * To change this template use File | Settings | File Templates.
 */
package editor.ui {
import alternativa.engine3d.controllers.SimpleObjectController;
import alternativa.engine3d.core.Camera3D;
import alternativa.engine3d.core.Object3D;
import alternativa.engine3d.core.Resource;
import alternativa.engine3d.core.View;
import alternativa.engine3d.core.events.MouseEvent3D;
import alternativa.engine3d.materials.FillMaterial;
import alternativa.engine3d.objects.Mesh;
import alternativa.engine3d.primitives.GeoSphere;
import alternativa.engine3d.primitives.Plane;

import editor.BeansFactory;

import flash.display.Stage3D;
import flash.events.Event;
import flash.geom.Point;

import mx.collections.ArrayCollection;
import mx.core.UIComponent;

import vplib.component.IPhysicsComponent;

public class ScreenXYZ extends UIComponent {
    private var stage3D:Stage3D;
    private var _camera:Camera3D;
    private var _scene:Object3D;
    private var controller:SimpleObjectController;

    public function ScreenXYZ() {
        _scene = new Object3D();

        if (stage) onAddedToStage();
        else addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

        trace("[ScreenXYZ] \t- Create new instance.");
    }

    private function onAddedToStage(event:Event = null):void {
        removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

        _camera = new Camera3D(1, 1000);
        _camera.x = 100;
        _camera.y = 100;
        _camera.z = 100;
        controller = new SimpleObjectController(stage, _camera, 200);
        controller.lookAtXYZ(0, 0, 0);
        _camera.view = new View(800, 600, false, 0xFFFFFF, 0, 4);
        this.drawBorderAroundView();
        addChild(_camera.view);
        addChild(_camera.diagram);

        _scene.addChild(_camera);

        var center:Mesh = new GeoSphere(5, 5, false, new FillMaterial(0x0));
        _scene.addChild(center);

        var groundMaterial:FillMaterial = new FillMaterial(0x009900, 0.5);
        var ground:Plane = new Plane(200, 200, 10, 10, true, true, groundMaterial, groundMaterial);
        _scene.addChild(ground);

        stage3D = stage.stage3Ds[0];
        stage3D.addEventListener(Event.CONTEXT3D_CREATE, onCreateContext3D);
        stage3D.requestContext3D();
    }

    public function setViewSize(size:Point):void {
        _camera.view.width = size.x;
        _camera.view.height = size.y;
        this.drawBorderAroundView();
    }

    private function drawBorderAroundView():void {
        graphics.clear();
        graphics.lineStyle(3, 0x999999);
        graphics.drawRoundRect(
                _camera.view.x,
                _camera.view.y,
                _camera.view.width,
                _camera.view.height,
                20, 20
        );
    }

    private function onCreateContext3D(event:Event = null):void {
        for each (var resource:Resource in _scene.getResources(true)) {
            resource.upload(stage3D.context3D);
        }

        addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        _scene.addEventListener(MouseEvent3D.CLICK, onClickScene);
        trace("[" + this.className + "] \t- onCreateContext3D - Init resources.");
    }

    private function enterFrameHandler(event:Event):void {
        controller.update();
        _camera.render(stage3D);
    }

    public function addComponents(components:ArrayCollection):void {
        for each (var component:IPhysicsComponent in components)
            this.addComponent(component);
        trace("[" + this.className + "] \t- addComponents - Count: " + components.length);
    }

    public function addComponent(component:IPhysicsComponent):void {
        component.applyModelToSurface();
        _scene.addChild(component.getSurface());
        component.getSurface().geometry.upload(stage3D.context3D);

        trace("[ScreenXYZ] \t- addComponent -> " + component.getComponentName() + ".");
    }

    public function editComponent(component:IPhysicsComponent):void {
        var surface:Mesh = (_scene.getChildByName(component.getSurface().name) as Mesh);
        surface = component.getSurface();

//        component.applyModelToSurface();
//        _scene.addChild(component.getSurface());
//        component.getSurface().geometry.upload(stage3D.context3D);

        trace("[ScreenXYZ] \t- editComponent -> " + component.getComponentName() + ".");
    }

    public function removeComponent(component:IPhysicsComponent):void {
        _scene.removeChild(component.getSurface());
        trace("[" + this.className + "] \t- Remove component -> " + component.getComponentName() + ".");
    }

    private function onClickScene(event:MouseEvent3D):void {
        try {
            var surface:Mesh = (event.target as Mesh);
            var selectedComponent = BeansFactory.getLabWork().getComponentBySurface(surface);
            if (selectedComponent != null) {
                BeansFactory.setSelectedComponent(selectedComponent);
                BeansFactory.getPropertiesComponentList().init(selectedComponent);
                trace("[VPLEditorView] \t- onClickScene - Select component on scene " + event.target);
            } else {
                BeansFactory.getPropertiesComponentList().clearFields();
                trace("[VPLEditorView] \t- onClickScene - Select component on scene, which not exists in scene components list " + event.target);
            }
        } catch (error:Error) {
            trace(error);
        }
    }
}
}
